import java.io.*;
import java.util.ArrayList;
import org.jsoup.*;
import org.jsoup.nodes.*;
import org.jsoup.select.Elements;

public class MaxStatsParser {
	
	static ArrayList<MaxStats> allPlayers;
	static FileWriter writer;
	static Elements els;
	static Elements totals;
	static ArrayList<MaxStats> storedPlayers;
	static final int SEASON_TOTALS = -1;
	static String regionNum;
	static String division;
	static String team;
	static double winningPer;

	public static void main(String[] args) {
		allPlayers = new ArrayList<MaxStats>();
		try{
			  FileInputStream fstream = new FileInputStream(args[0]);
			  DataInputStream in = new DataInputStream(fstream);
			  BufferedReader br = new BufferedReader(new InputStreamReader(in));
			  String strLine;
			  while ((strLine = br.readLine()) != null) {
				  try{
					  Jsoup.connect(strLine).get();
					  parse(strLine);
					  writecsv(strLine, args[1]);
				  } catch (Exception e){
					  System.out.println(strLine);
				  }
			  }
			  if(storedPlayers != null)
					allPlayers.addAll(storedPlayers);
			  writeAllPlayercsv(args[1]);
			  in.close();
		}catch (Exception e){//Catch exception if any
			  System.err.println("Error: " + e.getMessage());
			  e.printStackTrace();
		}
		
	}
	
	protected static Void parse(String url) {
		if(storedPlayers != null)
			allPlayers.addAll(storedPlayers);
		storedPlayers = new ArrayList<MaxStats>();
        Document doc = null;
        try {
            doc = Jsoup.connect(url).timeout(0).get();
        } catch (IOException e) {
            e.printStackTrace();
        }
        assignDivReg(doc);
        String docTitle = doc.select("head").first().text();
        String[] nameAndLocation = docTitle.split("[(*)]");
        team = (nameAndLocation[0].contains(" High School")) ? nameAndLocation[0].replace(" High School", "") : nameAndLocation[0];
        //team = nameAndLocation[0];
        els = doc.select("tbody");
        for(Element e: els){
        	Elements players = e.children();
        	for(Element player: players){
        		makePlayer(player);
        	}
        }
        totals = doc.select("tfoot");
        for(Element e: totals){
        	Elements players = e.children();
        	for(Element player: players){
        		makePlayer(player);
        	}
        }
        System.out.println(docTitle + "..........................Done!");
        return null;    
    }
	
	private static void makePlayer(Element player){
		MaxStats tempPlayer;
		Elements playerinfo = player.children();
		int tempjersey;
		if(playerinfo.first().text().equals("")){
			makeSeasonTotals(playerinfo);
			return;
		}
		else{
			tempjersey = Integer.parseInt(playerinfo.first().text());
		}
		if(alreadyStored(tempjersey)){
			tempPlayer = getPlayer(tempjersey);
			storedPlayers.remove(getPlayer(tempjersey));
		}
		else{
			tempPlayer = new MaxStats();
		}
		for(Element info: playerinfo){
			assignValue(tempPlayer, info.attr("class"), info.text());
			if(info.children().size() > 1)
				assignName(tempPlayer, info.children());
		}
		tempPlayer.team(team);
		tempPlayer.division(division);
		tempPlayer.region(regionNum);
		tempPlayer.winPer(winningPer);
		storedPlayers.add(tempPlayer);
	}
	
	private static void makeSeasonTotals(Elements playerinfo){
		MaxStats tempPlayer;
		if(playerinfo.get(1).text().equals("Season Totals")){
			if(alreadyStored(SEASON_TOTALS)){
				tempPlayer = getPlayer(SEASON_TOTALS);
				storedPlayers.remove(getPlayer(SEASON_TOTALS));
			}
			else{
				tempPlayer = new MaxStats();
			}
			for(Element info: playerinfo){
				assignValue(tempPlayer, info.attr("class"), info.text());
			}
			tempPlayer.playerName("Season Totals");
			storedPlayers.add(tempPlayer);
		}
	}
	
	private static void assignValue(MaxStats player, String field, String val){
		if(field.length() > 5 && field.substring(0,6).equals("jersey") && val.equals("")){ player.jersey(-1); return; }
		if(val.equals("")) val = "0";
		
		if(field.length() > 5 && field.substring(0,6).equals("jersey")){ player.jersey((Integer.parseInt(val))); }
		else if(field.equals("gamesplayed stat narrow")){ player.gamesPlayed(Integer.parseInt(val)); }
		else if(field.equals("gamesplayed stat")){ player.gamesPlayed(Integer.parseInt(val)); }
		else if(field.equals("gamesplayed stat wide")){ player.gamesPlayed(Integer.parseInt(val)); }
		else if(field.equals("pointspergame stat")){ player.ppg(Double.parseDouble(val)); }
		else if(field.equals("pointspergame stat narrow")){ player.ppg(Double.parseDouble(val)); }
		else if(field.equals("pointspergame stat wide")){ player.ppg(Double.parseDouble(val)); }
		else if(field.equals("points stat")){ player.points(Integer.parseInt(val)); }
		else if(field.equals("points stat narrow")){ player.points(Integer.parseInt(val)); }
		else if(field.equals("points stat wide")){ player.points(Integer.parseInt(val)); }
		else if(field.equals("fieldgoalsmade stat")){ player.fgmade(Integer.parseInt(val)); }
		else if(field.equals("fieldgoalsmade stat narrow")){ player.fgmade(Integer.parseInt(val)); }
		else if(field.equals("fieldgoalsmade stat wide")){ player.fgmade(Integer.parseInt(val)); }
		else if(field.equals("fieldgoalattempts stat")){ player.fgattempted(Integer.parseInt(val)); }
		else if(field.equals("fieldgoalattempts stat narrow")){ player.fgattempted(Integer.parseInt(val)); }
		else if(field.equals("fieldgoalattempts stat wide")){ player.fgattempted(Integer.parseInt(val)); }
		else if(field.equals("twopointsmade stat")){ player.twosmade(Integer.parseInt(val)); }
		else if(field.equals("twopointsmade stat narrow")){ player.twosmade(Integer.parseInt(val)); }
		else if(field.equals("twopointsmade stat wide")){ player.twosmade(Integer.parseInt(val)); }
		else if(field.equals("twopointattempts stat")){ player.twosattempted(Integer.parseInt(val)); }
		else if(field.equals("twopointattempts stat narrow")){ player.twosattempted(Integer.parseInt(val)); }
		else if(field.equals("twopointattempts stat wide")){ player.twosattempted(Integer.parseInt(val)); }
		else if(field.equals("threepointsmade stat")){ player.threesmade(Integer.parseInt(val)); }
		else if(field.equals("threepointsmade stat narrow")){ player.threesmade(Integer.parseInt(val)); }
		else if(field.equals("threepointsmade stat wide")){ player.threesmade(Integer.parseInt(val)); }
		else if(field.equals("threepointattempts stat wide")){ player.threesattempted(Integer.parseInt(val)); }
		else if(field.equals("freethrowsmade stat")){ player.ftmade(Integer.parseInt(val)); }
		else if(field.equals("freethrowsmade stat narrow")){ player.ftmade(Integer.parseInt(val)); }
		else if(field.equals("freethrowsmade stat wide")){ player.ftmade(Integer.parseInt(val)); }
		else if(field.equals("freethrowattempts last stat")){ player.ftattempted(Integer.parseInt(val)); }
		else if(field.equals("freethrowattempts last stat narrow")){ player.ftattempted(Integer.parseInt(val)); }
		else if(field.equals("freethrowattempts last stat wide")){ player.ftattempted(Integer.parseInt(val)); }
		else if(field.equals("fieldgoalpercentage stat")){ player.fgper(Double.parseDouble(val)); }
		else if(field.equals("fieldgoalpercentage stat narrow")){ player.fgper(Double.parseDouble(val)); }
		else if(field.equals("fieldgoalpercentage stat wide")){ player.fgper(Double.parseDouble(val)); }
		else if(field.equals("twopointpercentage stat")){ player.twosper(Double.parseDouble(val)); }
		else if(field.equals("twopointpercentage stat narrow")){ player.twosper(Double.parseDouble(val)); }
		else if(field.equals("twopointpercentage stat wide")){ player.twosper(Double.parseDouble(val)); }
		else if(field.equals("threepointpercentage stat")){ player.threesper(Double.parseDouble(val)); }
		else if(field.equals("threepointpercentage stat narrow")){ player.threesper(Double.parseDouble(val)); }
		else if(field.equals("threepointpercentage stat wide")){ player.threesper(Double.parseDouble(val)); }
		else if(field.equals("freethrowpercentage last stat")){ player.ftper(Double.parseDouble(val)); }
		else if(field.equals("freethrowpercentage last stat narrow")){ player.ftper(Double.parseDouble(val)); }
		else if(field.equals("freethrowpercentage last stat wide")){ player.ftper(Double.parseDouble(val)); }
		else if(field.equals("assists stat")){ player.assists(Integer.parseInt(val)); }
		else if(field.equals("assists stat narrow")){ player.assists(Integer.parseInt(val)); }
		else if(field.equals("assists stat wide")){ player.assists(Integer.parseInt(val)); }
		else if(field.equals("assistspergame stat")){ player.apg(Double.parseDouble(val)); }
		else if(field.equals("assistspergame stat narrow")){ player.apg(Double.parseDouble(val)); }
		else if(field.equals("assistspergame stat wide")){ player.apg(Double.parseDouble(val)); }
		else if(field.equals("blockedshots stat")){ player.blocks(Integer.parseInt(val)); }
		else if(field.equals("blockedshots stat narrow")){ player.blocks(Integer.parseInt(val)); }
		else if(field.equals("blockedshots stat wide")){ player.blocks(Integer.parseInt(val)); }
		else if(field.equals("blockspergame stat")){ player.bpg(Double.parseDouble(val)); }
		else if(field.equals("blockspergame stat narrow")){ player.bpg(Double.parseDouble(val)); }
		else if(field.equals("blockspergame stat wide")){ player.bpg(Double.parseDouble(val)); }
		else if(field.equals("offensiverebounds stat")){ player.offReb(Integer.parseInt(val)); }
		else if(field.equals("offensiverebounds stat narrow")){ player.offReb(Integer.parseInt(val)); }
		else if(field.equals("offensiverebounds stat wide")){ player.offReb(Integer.parseInt(val)); }
		else if(field.equals("defensiverebounds stat")){ player.defReb(Integer.parseInt(val)); }
		else if(field.equals("defensiverebounds stat narrow")){ player.defReb(Integer.parseInt(val)); }
		else if(field.equals("defensiverebounds stat wide")){ player.defReb(Integer.parseInt(val)); }
		else if(field.equals("rebounds stat")){ player.totReb(Integer.parseInt(val)); }
		else if(field.equals("rebounds stat narrow")){ player.totReb(Integer.parseInt(val)); }
		else if(field.equals("rebounds stat wide")){ player.totReb(Integer.parseInt(val)); }
		else if(field.equals("reboundspergame stat")){ player.rpg(Double.parseDouble(val)); }
		else if(field.equals("reboundspergame stat narrow")){ player.rpg(Double.parseDouble(val)); }
		else if(field.equals("reboundspergame stat wide")){ player.rpg(Double.parseDouble(val)); }
		else if(field.equals("steals stat")){ player.steals(Integer.parseInt(val)); }
		else if(field.equals("steals stat narrow")){ player.steals(Integer.parseInt(val)); }
		else if(field.equals("steals stat wide")){ player.steals(Integer.parseInt(val)); }
		else if(field.equals("stealspergame stat")){ player.spg(Double.parseDouble(val)); }
		else if(field.equals("stealspergame stat narrow")){ player.spg(Double.parseDouble(val)); }
		else if(field.equals("stealspergame stat wide")){ player.spg(Double.parseDouble(val)); }
		else if(field.equals("deflections last stat")){ player.deflections(Integer.parseInt(val)); }
		else if(field.equals("deflections last stat narrow")){ player.deflections(Integer.parseInt(val)); }
		else if(field.equals("deflections last stat wide")){ player.deflections(Integer.parseInt(val)); }
		else if(field.equals("turnovers stat")){ player.turnovers(Integer.parseInt(val)); }
		else if(field.equals("turnovers stat narrow")){ player.turnovers(Integer.parseInt(val)); }
		else if(field.equals("turnovers stat wide")){ player.turnovers(Integer.parseInt(val)); }
		else if(field.equals("personalfouls stat")){ player.fouls(Integer.parseInt(val)); }
		else if(field.equals("personalfouls stat narrow")){ player.fouls(Integer.parseInt(val)); }
		else if(field.equals("personalfouls stat wide")){ player.fouls(Integer.parseInt(val)); }
		else if(field.equals("technicalfouls stat")){ player.techs(Integer.parseInt(val)); }
		else if(field.equals("technicalfouls stat narrow")){ player.techs(Integer.parseInt(val)); }
		else if(field.equals("technicalfouls stat wide")){ player.techs(Integer.parseInt(val)); }
		else if(field.equals("charges last stat")){ player.charges(Integer.parseInt(val)); }
		else if(field.equals("charges last stat narrow")){ player.charges(Integer.parseInt(val)); }
		else if(field.equals("charges last stat wide")){ player.charges(Integer.parseInt(val)); }
		else if(field.equals("name")){}
		else
			System.out.println(field);
	}
	
	private static void assignName(MaxStats player, Elements e){
		for(Element t: e){
			if(t.tagName().equals("a")){
				player.playerName(t.attr("title"));
				getHeightWeight(player, t.attr("href"));
			}
			else if(t.tagName().equals("abbr"))
				player.gradClass(t.attr("title"));
		}
	}
	
	private static boolean alreadyStored(int jersey){
		for(MaxStats player: storedPlayers){
			if(player.getJersey() == jersey)
				return true;
		}
		return false;
	}
	
	private static MaxStats getPlayer(int jersey){
		for(MaxStats player: storedPlayers){
			if(player.getJersey() == jersey)
				return player;
		}
		return null;
	}
	
	private static void writecsv(String name, String stateName){
		try {
			String properName = extractNameFromURL(name);
			writer = new FileWriter("C:\\Users\\Dallin\\Downloads\\" + stateName + " Stats\\" + properName + ".csv");
			writer.append("#, Name, Class, Height, Weight, GP, PPG, Pts, FGM, FGA, FG%, 2FGM, 2FGA, 2FG%, 3FGM, 3FGA, 3FG%, " +
						  "FTM, FTA, FT%, Asst, APG, BlkShts, BPG, Off Reb, Def Reb, Tot Reb, RPG, " +
						  "Stls, SPG, Defl, TO, PF, TechF, Charges");
			writer.append('\n');
			
			for(MaxStats player: storedPlayers){
				writer.append(player.csv(false));
				writer.append('\n');
			}
			
			writer.flush();
		    writer.close();
		    
		} catch (Exception e) {
			e.printStackTrace();
		}	
	}
	
	private static void writeAllPlayercsv(String stateName){
		try {
			boolean success = (new File("C:\\Users\\Dallin\\Downloads\\Stats\\")).mkdirs();
			writer = new FileWriter("C:\\Users\\Dallin\\Downloads\\Stats\\" + stateName + " - all players.csv");
			writer.append("Team, Win%, Div, #, Name, Class, Height, Weight, GP, PPG, Pts, FGM, FGA, " +
						  "FG%, 2FGM, 2FGA, 2FG%, 3FGM, 3FGA, 3FG%, FTM, FTA, FT%, Asst, APG, " +
						  "BlkShts, BPG, Off Reb, Def Reb, Tot Reb, RPG, " +
						  "Stls, SPG, Defl, TO, PF, TechF, Charges");
			writer.append('\n');
			
			for(MaxStats player: allPlayers){
				try{
					if(player.playerName.equals("Season Totals")) continue;
					writer.append(player.csv(true));
					writer.append('\n');
				}
				catch(Exception e){
					System.out.println(player.toString());
				}
			}
			
			writer.flush();
		    writer.close();
		    
		} catch (Exception e) {
			e.printStackTrace();
		}	
	}
	
	private static String extractNameFromURL(String url){
		String base = "http://www.maxpreps.com/high-schools/";
		String name = url.substring(base.length(), url.length());
		name = name.substring(0,name.indexOf('/'));
		return name;
	}
	
	private static void assignDivReg(Document doc){
		Elements findRegion = doc.select("dd");
        for(Element e: findRegion){
        	if(e.toString().contains("standings-") && !e.toString().contains("standings-popout") && e.toString().contains("Overall")){
        		Element link = e.child(0);
        		
        		//Utah        		
//        		String divregion = link.toString();
//        		divregion = divregion.substring(divregion.indexOf('-') + 1,divregion.lastIndexOf('.'));
//        		if(!divregion.substring(0, 1).matches("[12345]")){
//        			divregion = divregion.substring(divregion.indexOf('-') + 1);
//        		}
//        		String[] divided = divregion.split("-");
//        		regionNum = divided[2];
//        		division = divided[0];
        		//end Utah
        		
        		//Nevada        		
        		String divregion = link.toString();
        		divregion = divregion.substring(divregion.indexOf('-') + 1,divregion.lastIndexOf('.'));
        		while(divregion.contains("/"))
        			divregion = divregion.substring(divregion.indexOf('/') + 1, divregion.length());
        		if(divregion.contains("standings"))
        			divregion = divregion.substring(10, divregion.length());
        		regionNum = divregion;
        		division = divregion;
        		//end Nevada
        		
        		
        		winPercent(e.text());
        	}
        }
	}
	
	private static void winPercent(String s){
		String[] winloss = s.split("-");
		int wins = Integer.parseInt(winloss[0]);
		int losses = Integer.parseInt(winloss[1]);
		winningPer = (double) wins/(wins+losses);
	}
	
	private static void getHeightWeight(MaxStats player, String url){
		Document page = null;
		try {
			page = Jsoup.connect("http://www.maxpreps.com" + url).timeout(0).get();
		} catch (IOException e) {
			e.printStackTrace();
		}
    
		Elements htwt = page.select("dd");
		for(Element e: htwt){
			if(e.toString().contains("&quot;/")){
				String[] body = e.text().split("[&quot;/]");
				player.height(body[0]);
				player.weight(body[1]);
			}
			else if(e.toString().contains("&quot;") && e.toString().contains("'")){
				String[] body = e.text().split("[&quot;]");
				player.height(body[0]);
				player.weight("n/a");
			}
		}
	}
}
